﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using IPC.Communication.BasicFramework;
using IPC.Communication.Core;
using IPC.Communication.Reflection;
using IPC.Communication.Serial;

namespace IPC.Communication.Profinet.Panasonic
{
    public class PanasonicMewtocol : SerialDeviceBase
    {
        public byte Station
        {
            get;
            set;
        }

        public PanasonicMewtocol(byte station = 238)
        {
            base.ByteTransform = new RegularByteTransform();
            Station = station;
            base.ByteTransform.DataFormat = DataFormat.DCBA;
        }

        [HslMqttApi("ReadByteArray", "")]
        public override OperateResult<byte[]> Read(string address, ushort length)
        {
            byte station = (byte)HslHelper.ExtractParameter(ref address, "s", Station);
            OperateResult<byte[]> operateResult = PanasonicHelper.BuildReadCommand(station, address, length);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            return PanasonicHelper.ExtraActualData(operateResult2.Content);
        }

        [HslMqttApi("WriteByteArray", "")]
        public override OperateResult Write(string address, byte[] value)
        {
            byte station = (byte)HslHelper.ExtractParameter(ref address, "s", Station);
            OperateResult<byte[]> operateResult = PanasonicHelper.BuildWriteCommand(station, address, value);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            return PanasonicHelper.ExtraActualData(operateResult2.Content);
        }

        [HslMqttApi("ReadBoolArray", "")]
        public override OperateResult<bool[]> ReadBool(string address, ushort length)
        {
            byte station = (byte)HslHelper.ExtractParameter(ref address, "s", Station);
            OperateResult<string, int> operateResult = PanasonicHelper.AnalysisAddress(address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult);
            }
            OperateResult<byte[]> operateResult2 = PanasonicHelper.BuildReadCommand(station, address, length);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult2);
            }
            OperateResult<byte[]> operateResult3 = ReadFromCoreServer(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult3);
            }
            OperateResult<byte[]> operateResult4 = PanasonicHelper.ExtraActualData(operateResult3.Content);
            if (!operateResult4.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult4);
            }
            return OperateResult.CreateSuccessResult(SoftBasic.ByteToBoolArray(operateResult4.Content).SelectMiddle(operateResult.Content2 % 16, length));
        }

        [HslMqttApi("ReadBool", "")]
        public override OperateResult<bool> ReadBool(string address)
        {
            byte station = (byte)HslHelper.ExtractParameter(ref address, "s", Station);
            OperateResult<byte[]> operateResult = PanasonicHelper.BuildReadOneCoil(station, address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool>(operateResult);
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool>(operateResult2);
            }
            return PanasonicHelper.ExtraActualBool(operateResult2.Content);
        }

        [HslMqttApi("WriteBoolArray", "")]
        public override OperateResult Write(string address, bool[] values)
        {
            byte station = (byte)HslHelper.ExtractParameter(ref address, "s", Station);
            OperateResult<string, int> operateResult = PanasonicHelper.AnalysisAddress(address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult);
            }
            if (operateResult.Content2 % 16 != 0)
            {
                return new OperateResult(StringResources.Language.PanasonicAddressBitStartMulti16);
            }
            if (values.Length % 16 != 0)
            {
                return new OperateResult(StringResources.Language.PanasonicBoolLengthMulti16);
            }
            byte[] values2 = SoftBasic.BoolArrayToByte(values);
            OperateResult<byte[]> operateResult2 = PanasonicHelper.BuildWriteCommand(station, address, values2);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            OperateResult<byte[]> operateResult3 = ReadFromCoreServer(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return operateResult3;
            }
            return PanasonicHelper.ExtraActualData(operateResult3.Content);
        }

        [HslMqttApi("WriteBool", "")]
        public override OperateResult Write(string address, bool value)
        {
            byte station = (byte)HslHelper.ExtractParameter(ref address, "s", Station);
            OperateResult<byte[]> operateResult = PanasonicHelper.BuildWriteOneCoil(station, address, value);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            return PanasonicHelper.ExtraActualData(operateResult2.Content);
        }

        //[AsyncStateMachine(typeof(<ReadBoolAsync>d__11))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<bool>> ReadBoolAsync(string address)
        //{
        //    <ReadBoolAsync>d__11 stateMachine = new <ReadBoolAsync>d__11();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__12))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, bool value)
        //{
        //    <WriteAsync>d__12 stateMachine = new <WriteAsync>d__12();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        public override string ToString()
        {
            return String.Format("Panasonic Mewtocol[{0}:{1}]", base.PortName, base.BaudRate);
        }
    }
}